package com.carsa.blackberry.domain.dto;

import java.util.Enumeration;
import java.util.Vector;

import com.carsa.blackberry.domain.services.webServices.impl.ZSdareEntrega.ZSdareEntregable;
import com.carsa.blackberry.domain.services.webServices.impl.ZSdareEntrega.ZsdareEntrega;
import com.carsa.blackberry.util.Comparable;
import com.carsa.blackberry.util.Util;
import com.carsa.blackberry.util.XMLHandler;
import com.carsa.blackberry.util.XMLPortable;

/**
 * @author Nahuel Barrios.
 * @since 27/08/2010.
 * @version 1.0
 */
public class EntregaDTO implements ZSdareEntregable, XMLPortable, Comparable {

	private static final String XML_ELEMENT_CALIFIED = "calified";

	private static final String XML_ELEMENT_ARTICLES = "articles";

	private static final int SUCCESS = 0;
	private static final int FAIL = 1;

	private Vector _articles = new Vector();

	private boolean _calified;

	// Estos atributos son iguales para todas las entregas, no dependen del
	// articulo.
	private String vbeln;
	private String name1;
	private String name2;
	private String direc;
	private String city1;
	private String sammg;
	private String telNumber;
	private String observaciones;

	public EntregaDTO(String xmlSource) {
		super();
		this.initializeFromXML(xmlSource);
	}

	public EntregaDTO(ArticuloDTO anArticle) {
		super();
		this._articles.addElement(anArticle);
		this.initializeFromObject(anArticle);
	}

	public EntregaDTO() {
	}

	/**
	 * @return <code>true</code> si esta entrega ya fue calificada en cualquiera
	 *         de sus formas.
	 */
	public boolean isCalified() {
		return _calified;
	}

	public boolean hasAnyArticleAsSuccess() {
		return this.iterateFor(SUCCESS);
	}

	public boolean hasAnyArticleAsFail() {
		return this.iterateFor(FAIL);
	}

	public boolean iterateFor(int typeOfSearch) {
		Enumeration articles = this._articles.elements();
		while (articles.hasMoreElements()) {
			ArticuloDTO eachArticle = (ArticuloDTO) articles.nextElement();

			switch (typeOfSearch) {
			case SUCCESS:
				if (eachArticle.wasCalifiedAsSuccess())
					return true;
				break;
			case FAIL:
				if (eachArticle.wasCalifiedAsFail())
					return true;
				break;
			default:
				break;
			}
		}

		return false;
	}

	/**
	 * @param calified
	 *            <code>true</code> si esta entrega ya fue calificada en
	 *            cualquiera de sus formas. Por default tiene un valor de false.
	 */
	public void setCalified(boolean calified) {
		_calified = calified;
	}

	/**
	 * @param anArticle
	 */
	// TODO : Javadoc : Terminate this Javadoc.
	public void initializeFromObject(ArticuloDTO anArticle) {
		this.vbeln = anArticle.getVbeln();
		this.name1 = anArticle.getInputWSObject().getName1();
		this.name2 = anArticle.getInputWSObject().getName2();
		this.direc = anArticle.getInputWSObject().getDirec();
		this.city1 = anArticle.getInputWSObject().getCity1();
		this.sammg = anArticle.getSammg();
//		this.observaciones= anArticle.getInputWSObject().getObservaciones();TODO Descomentar esto!!
		this.telNumber = anArticle.getInputWSObject().getTelNumber();
	}

	public void addArticle(ArticuloDTO unArticulo) {
		if (unArticulo != null)
			this._articles.addElement(unArticulo);

		if (this.name1 == null)
			this.initializeFromObject(unArticulo);
	}

	public String toXMLString() {
		XMLHandler xml = new XMLHandler("unaEntrega", null, null);

		xml.addElementAtRoot(XML_ELEMENT_CALIFIED, null, new Boolean(_calified)
				.toString());

		XMLHandler xmlArticles = new XMLHandler(XML_ELEMENT_ARTICLES, null,
				null);
		Enumeration articulos = _articles.elements();
		while (articulos.hasMoreElements()) {
			ArticuloDTO eachArticle = (ArticuloDTO) articulos.nextElement();

			xmlArticles.addElementAtRoot(eachArticle.toXMLString());
		}

		xml.addElementAtRoot(xmlArticles.toXMLString());

		return xml.toXMLString();
	}

	/**
	 * @return
	 */
	// TODO : Javadoc : Terminate this Javadoc.
	public boolean hasMoreThanOneArticles() {
		return this.getArticlesCount() > 1;
	}

	/**
	 * @return the _articulos
	 */
	public Vector getArticles() {
		return _articles;
	}

	public String toString() {
		return "EntregaDTO [  city1=" + city1 + ",  direc=" + direc
				+ ",  name1=" + name1 + ",  name2=" + name2 + ",  sammg="
				+ sammg + ",  telNumber=" + telNumber + ",  vbeln=" + vbeln
				+ "  ]";
	}

	/**
	 * @return La cantidad de articulos que tiene esta {@link EntregaDTO}
	 */
	public int getArticlesCount() {
		return this._articles.size();
	}

	public void initializeFromXML(String xmlSource) {
		XMLHandler xml = new XMLHandler(xmlSource);

		this._calified = Util.getBooleanConditionFrom(xml
				.getElementValue(XML_ELEMENT_CALIFIED));

		xml = new XMLHandler(xml.getElementValue(XML_ELEMENT_ARTICLES));

		int elementsCount = xml.getElementCount();

		int idx = 0;
		for (idx = 0; idx < elementsCount; idx++) {
			ArticuloDTO anElement = new ArticuloDTO(xml
					.getFirstElementValueOverIteration());
			_articles.addElement(anElement);
		}

		this.initializeFromObject((ArticuloDTO) _articles.elementAt(0));
	}

	public int compareTo(Object obj) {
		EntregaDTO comparedObject = (EntregaDTO) obj;

		if (this.getArticlesCount() == comparedObject.getArticlesCount()) {
			Enumeration myArticles = _articles.elements();
			Enumeration theirArticles = comparedObject.getArticles().elements();

			while (myArticles.hasMoreElements()) {
				ZsdareEntrega miEntrega = (ZsdareEntrega) myArticles
						.nextElement();
				ZsdareEntrega suEntrega = (ZsdareEntrega) theirArticles
						.nextElement();

				int comparison = miEntrega.getVbeln().compareTo(
						suEntrega.getVbeln());
				if (comparison != 0)
					return comparison;
			}

			return 0;
		}
		return -1;
	}

	/**
	 * @return Un {@link String} con el numero de entrega.
	 */
	public String getVbeln() {
		return vbeln;
	}

	/**
	 * @return Un {@link String} con el apellido del cliente.
	 */
	public String getName1() {
		return name1;
	}

	/**
	 * @return Un {@link String} con el nombre del cliente.
	 */
	public String getName2() {
		return name2;
	}

	/**
	 * @return Un {@link String} con la direccion donde realizar la entrega.
	 */
	public String getDirec() {
		return direc;
	}
	
	/**
	 * @return Un {@link String} con las observaciones.
	 */
	public String getObservaciones() {
		return observaciones;
	}
	

	/**
	 * @return Un {@link String} con la ciudad donde realizar la entrega.
	 */
	public String getCity1() {
		return city1;
	}

	/**
	 * @return Un {@link String} con el numero de grupo de entregas.
	 */
	public String getSammg() {
		return sammg;
	}

	/**
	 * @return Un {@link String} con el numero de telefono del cliente.
	 */
	public String getTelNumber() {
		return telNumber;
	}

	public boolean isPending() {
		return !this.isCalified();
	}

	// /**
	// * @return
	// */
	// public boolean isPending() {
	// ArticuloDTO anArticle = (ArticuloDTO) _articles.elementAt(0);
	// String feare = anArticle.getOutputWSObject().getFeare();
	// return feare == null || feare.equalsIgnoreCase("null");
	// }

}
